﻿using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using Sasa.QualityTools.CodeAnalysis.Core.VisualStudio;
using Sasa.QualityTools.CodeAnalysis.Common;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Commands.Behaviors;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Commands
{
    public abstract class CommandBase<TContext> : ICommand
        where TContext : CommandExecutionContext, new()
    {
        protected IUnityContainer Container { get; private set; }

        protected ICollection<ICommandBehavior<TContext>> Behaviors { get; private set; }


        protected CommandBase(IUnityContainer container)
        {
            Container = container;
            Behaviors = new List<ICommandBehavior<TContext>>();
        }


        public void Execute()
        {
            PreExecute();

            var ide = Container.Resolve<IIde>();
            var context = new TContext();

            foreach (var behavior in Behaviors)
            {
                behavior.Behave(context);
                if (context.IsCanceled)
                {
                    ide.NotifyWarn(context.CanceledReason);
                    Logger.Warn(context.CanceledReason);
                    context.ExecuteAlternateAction();
                    break;
                }
            }

            PostExecute();
        }

        protected virtual void PreExecute()
        {
            Logger.Info("Executing the FxCop Integrator command ('{0}').", GetType().FullName);
        }

        protected virtual void PostExecute()
        {
            Logger.Info("Executed the FxCop Integrator command ('{0}').", GetType().FullName);
        }
    }
}
